package com.sidom.movieIndexer.service.clean;

import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import static org.apache.commons.lang.Validate.notNull;

import com.sidom.movieIndexer.domain.Movie;
import com.sidom.movieIndexer.domain.file.MovieFile;
import com.sidom.movieIndexer.service.clean.strategy.CleanFileNameStrategy;

/**
 * {@inheritDoc}.
 * 
 * @author Siebe
 */
@Service
public class CleanUpServiceImpl implements CleanUpService{
	/**
	 * Logger for the {@link CleanUpServiceImpl}.
	 */
	private Log log = LogFactory.getLog(CleanUpServiceImpl.class);
	
	/**
	 * A {@link List} of {@link CleanFileNameStrategy}s.
	 * Injected by Spring.
	 */
	@Autowired
	private List<CleanFileNameStrategy> cleanFileNameStrategies;
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Movie> cleanUpMovies(final List<Movie> movies) {
		return cleanUpFileNames(movies, cleanFileNameStrategies,null);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Movie> cleanUpMovies(final List<Movie> movies, final Set<String> wordsToRemove) {
		log.trace("Cleaning up movie files: " + movies + " with words to remove: " + wordsToRemove);
		cleanUpFileNames(movies, cleanFileNameStrategies, wordsToRemove);
		log.trace("Cleaned up movie files: " + movies);
		return movies;
	}
	
	/**
	 * Clean up a {@link List} of {@link Movie}s.
	 * @param movies A {@link Set} {@link Movie}s witch {@link Movie#getName()} need to be cleaned up using the {@link #cleanFileNameStrategies}
	 * @param cleanFileNameStrategies A {@link List} of {@link CleanFileNameStrategy} that need to be applied to all {@link Movie} names.
	 * @param wordsToRemove The words to remove from the {@link Movie#getName()} of the {@link Movie}.
	 * @return A {@link List} of {@link Movie}s with {@link MovieFile#getCleanedFileName()} information filled in.
	 */
	private List<Movie> cleanUpFileNames(final List<Movie> movies, final List<CleanFileNameStrategy> cleanFileNameStrategies, final Set<String> wordsToRemove){
		for (CleanFileNameStrategy cleanFileNameStrategy : cleanFileNameStrategies) {
			for (Movie movie : movies) {
				notNull(movie.getMovieFile(), "movieFile should not be null");
				if(StringUtils.isEmpty(movie.getMovieFile().getCleanedFileName())){
					movie.getMovieFile().setCleanedFileName(cleanFileNameStrategy.cleanFileName(movie.getMovieFile().getFileNameWithoutExtension(), wordsToRemove));
				}else{
					movie.getMovieFile().setCleanedFileName(cleanFileNameStrategy.cleanFileName(movie.getMovieFile().getCleanedFileName(), wordsToRemove));
				}
			}
		}
		return movies;
	}
	
	/**
	 * Check the attributes for null after the properties have been set.
	 */
	@PostConstruct
	public void afterPropertiesSet(){
		notNull(cleanFileNameStrategies);
	}
}
